// $--对象的类型标注
interface IDescription1 {
  name: string;
  age: number;
  male: boolean;
}
const obj1: IDescription1 = {
  name: 'linbudu',
  age: 599,
  male: true,
};

// $ 修饰接口属性
interface IDescription2 {
  name: string;
  age: number;
  male?: boolean;
  func?: Function;
}
const obj2: IDescription2 = {
  name: 'linbudu',
  age: 599,
  male: true,
  // 无需实现 func 也是合法的
};
obj2.male = false;
obj2.func = () => { return 2 };
console.log(obj2.func());


//$ readonly:它的作用是防止对象的属性被再次赋值。
interface IDescription3 {
  readonly name: string;
  readonly ary?: Array<number>,
  age: number;
}
const obj3: IDescription3 = {
  name: 'linbudu',
  age: 599,
  ary: [1, 2, 3]
};
let testAry1: [string?] = []
testAry1.push('lys')
// obj3.name = "刘毅松";// 无法分配到 "name" ，因为它是只读属性
obj3.ary.push(4)
console.log(obj3.ary);

//--object、Object 以及 { } 在 TypeScript 中就表现为 Object 包含了所有的类型：
// 对于 undefined、null、void 0 ，需要关闭 strictNullChecks
const tmp1a: Object = undefined;
const tmp2a: Object = null;
const tmp3a: Object = void 0;

const tmp44: Object = 'linbudu';
const tmp5: Object = 599;
const tmp6: Object = { name: 'linbudu' };
const tmp7: Object = () => { };
const tmp8: Object = [];

const tmp9: String = undefined;
const tmp10: String = null;
const tmp11: String = void 0;
const tmp12: String = 'linbudu';
const tmp121: string = 'linbudu';

// 以下不成立，因为不是字符串类型的拆箱类型
// const tmp13: String = 599; // X
// const tmp14: String = { name: 'linbudu' }; // X
// const tmp15: String = () => { }; // X
// const tmp16: String = []; // X


const tmp17: object = undefined;
const tmp18: object = null;
const tmp19: object = void 0;

//const tmp20: object = 'linbudu';  // X 不成立，值为原始类型
//const tmp21: object = 599; // X 不成立，值为原始类型

const tmp22: object = { name: 'linbudu' };
const tmp23: object = () => { };
const tmp24: object = [];


const tmp25: {} = undefined; // 仅在关闭 strictNullChecks 时成立，下同
const tmp26: {} = null;
const tmp27: {} = void 0; // void 0 等价于 undefined

const tmp28: {} = 'linbudu';
const tmp29: {} = 599;
const tmp30: { age?: number, name?: string } = { name: 'linbudu' };
const tmp300: {} = { name: 'linbudu' };
const tmp31: {} = () => { };
const tmp32: {} = [];


tmp30.age = 18; // X 类型“{}”上不存在属性“age”。


const uniqueSymbolFoo: unique symbol = Symbol("linbudu")

// 类型不兼容
// const uniqueSymbolBar: unique symbol = uniqueSymbolFoo


// declare const uniqueSymbolFoo22: unique symbol
// 在 TypeScript 中，如果要引用已创建的 unique symbol 类型，则需要使用类型查询操作符 typeof ：
const uniqueSymbolBaz: typeof uniqueSymbolFoo = uniqueSymbolFoo
console.log('uniqueSymbolBaz__', uniqueSymbolBaz);



const uniqueSymbolFoo2: unique symbol = Symbol(123);;
const uniqueSymbolBaz2: typeof uniqueSymbolFoo2 = uniqueSymbolFoo2
console.log('uniqueSymbolBaz2__', uniqueSymbolBaz2);


//当你不确定某个变量的具体类型，但能确定它不是原始类型，可以使用 object。但我更推荐进一步区分，也就是使用 Record<string, unknown> 或 Record<string, any> 表示对象，unknown[] 或 any[] 表示数组，(...args: any[]) => any表示函数这样。
const unknowObj: Record<string, unknown> = { name: 'str', ary: [] }